package com.qf.fifter;

import com.alibaba.fastjson2.JSON;
import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.FilterFactory;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.qf.config.RedisKey;
import com.qf.pojo.respVo.BaseResp;
import com.qf.utils.JWTUtils;
import jodd.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Component
@SuppressWarnings("all")
public class ZullMyFilter extends ZuulFilter {

    @Autowired
    RedisTemplate redisTemplate;

    private static List  urlList=new ArrayList<>();

    private RateLimiter rateLimiter=RateLimiter.create(20.0);
    @Override
    public String filterType() {
        return FilterConstants.PRE_TYPE;
    }

    @Override
    public int filterOrder() {
        return FilterConstants.PRE_DECORATION_FILTER_ORDER;
    }

    @Override
    public boolean shouldFilter() {
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        HttpServletResponse response = currentContext.getResponse();
        String requestURI = request.getRequestURI();
        String[] split = requestURI.split("/");
        if (urlList.contains(split[1])){
            return false;
        }
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        boolean b = rateLimiter.tryAcquire();
        //1验证用户是否是登录状态
        RequestContext currentContext = RequestContext.getCurrentContext();
        HttpServletRequest request = currentContext.getRequest();
        if (b){
        //如果是登录,首先去查看比对token串
            String token = request.getHeader("token");
            if (StringUtils.isEmpty(token)) {
                HttpServletResponse response = currentContext.getResponse();
                responseWriter(response,new BaseResp().Fail(0,"用户未登录!"));
                //阻止继续向后执行
                currentContext.setSendZuulResponse(false);
            }
            //2.验证redis中是否有该Key
            Boolean aBoolean = redisTemplate.hasKey(RedisKey.LOGIN_KEY + token);
            if (!aBoolean){
                HttpServletResponse response = currentContext.getResponse();
                responseWriter(response,new BaseResp().Fail(0,"登录失败!"));
                //阻止继续向后执行
                currentContext.setSendZuulResponse(false);
            }
            //3获取到redis中存储的token串
            Object o = redisTemplate.opsForValue().get(RedisKey.LOGIN_KEY + token);
            //4.使用jwtUtils解析
            Map map = JWTUtils.verfiyToken(o.toString());
            if (map==null){
                HttpServletResponse response = currentContext.getResponse();
                responseWriter(response,new BaseResp().Fail(0,"用户登录信息错误,请重试!"));
                //组织继续向后执行
                currentContext.setSendZuulResponse(false);
            }
        }else {
            HttpServletResponse response = currentContext.getResponse();
            responseWriter(response,new BaseResp().Fail(0,"服务器拥挤!"));
            currentContext.setSendZuulResponse(false);
        }
        //以上都逻辑都通过的情况下继续放行
        return null;
    }


    public void responseWriter(HttpServletResponse httpServletResponse, BaseResp baseResp){
        httpServletResponse.setCharacterEncoding("utf-8");
        httpServletResponse.setContentType("application/json");
        try {
            httpServletResponse.getWriter().write(JSON.toJSONString(baseResp));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public ZullMyFilter(){
        urlList.add("damai-user");
    }
}
